package com.yanggu.jt808.util;

import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;


/**
 * @author 杨顾
 */
@Slf4j
public class Jt808Util {

    private static final String HEX = "0123456789ABCDEF";

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 根据byteBuf的readerIndex和writerIndex计算校验码
     * 校验码规则：从消息头开始，同后一字节异或，直到校验码前一个字节，占用 1 个字节
     *
     * @param byteBuf
     * @return
     */
    public static byte xorSumBytes(ByteBuf byteBuf) {
        byte sum = byteBuf.getByte(byteBuf.readerIndex());
        for (int i = byteBuf.readerIndex() + 1; i < byteBuf.writerIndex(); i++) {
            sum = (byte) (sum ^ byteBuf.getByte(i));
        }
        return sum;
    }

    public static String bcdToString(byte bcd) {
        StringBuilder sb = new StringBuilder();

        byte high = (byte) (bcd & 0xf0);
        high >>>= (byte) 4;
        high = (byte) (high & 0x0f);
        byte low = (byte) (bcd & 0x0f);

        sb.append(high);
        sb.append(low);

        return sb.toString();
    }

    public static String bcdToString(byte[] bcd) {
        StringBuilder sb = new StringBuilder();

        for (byte b : bcd) {
            sb.append(bcdToString(b));
        }

        return sb.toString();
    }

    private static byte toByte(char c) {
        return (byte) HEX.indexOf(c);
    }

    public static byte[] toBcdBytes(String hex) {
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] charArray = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(charArray[pos]) << 4 | toByte(charArray[pos + 1]));
        }
        return result;
    }

    public static Date toBcdTimeString(byte[] bs) {
        if (bs.length != 6 && bs.length != 7) {
            log.error("无效BCD时间");
            return null;
        }
        StringBuilder sb = new StringBuilder();
        int i = 0;
        if (bs.length == 6) {
            sb.append("20");
        } else {
            sb.append(Jt808Util.bcdToString(bs[i++]));
        }
        sb.append(Jt808Util.bcdToString(bs[i++]));
        sb.append("-").append(Jt808Util.bcdToString(bs[i++]));
        sb.append("-").append(Jt808Util.bcdToString(bs[i++]));
        sb.append(" ").append(Jt808Util.bcdToString(bs[i++]));
        sb.append(":").append(Jt808Util.bcdToString(bs[i++]));
        sb.append(":").append(Jt808Util.bcdToString(bs[i]));
        try {
            LocalDateTime localDateTime = LocalDateTime.parse(sb.toString(), DATE_TIME_FORMATTER);
            return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        } catch (Exception e) {
            log.error("解析gpsUploadTime发生异常");
            return null;
        }
    }

}
